package devices

import (
	"context"
	"math/rand"
	"time"

	"gitee.com/zhuhuan12/go-modbus"
	"github.com/gogf/gf/v2/frame/g"
)

// FFU设备 - 基于config_params.c的默认配置
type FfuConfig struct {
	Product      string // 产品Key
	ModbusAddr   int8   // modbus地址
	SwitchStatus uint16 // 开关状态 (寄存器地址0x01)
	Speed        uint16 // 速度状态 (寄存器地址0x02)
	Temperature  uint16 // 温度状态 (寄存器地址0x03)
	Current      uint16 // 电流状态 (寄存器地址0x04)
	AlarmStatus  uint16 // 报警状态
	PressureDiff uint16 // 压差

	// 配置参数 - 基于config_params.c默认值
	TempDecimal    uint8  // 温度小数位 (默认0)
	CurrentDecimal uint8  // 电流小数位 (默认2)
	SpeedPower     uint8  // 速度转换系数 (默认1)
	MaxSpeed       uint16 // 最高速度 (默认1200)
	MinSpeed       uint16 // 最低速度 (默认300)
	HighSpeed      uint16 // 高速 (默认1000)
	MidSpeed       uint16 // 中速 (默认800)
	LowSpeed       uint16 // 低速 (默认400)

	// 内部状态
	lastUpdate       time.Time
	tempVariation    float32
	currentVariation float32
}

func (f *FfuConfig) NewDevice(modbusValue int8) Device {
	return &FfuConfig{
		ModbusAddr:   modbusValue,
		Product:      "ffu_config",
		SwitchStatus: 0,   // 默认关闭
		Speed:        0,   // 默认速度0
		Temperature:  250, // 默认温度25.0度 (小数位0)
		Current:      150, // 默认电流1.50A (小数位2)
		AlarmStatus:  0,   // 无报警
		PressureDiff: 0,   // 压差0

		// 配置参数
		TempDecimal:    0,
		CurrentDecimal: 2,
		SpeedPower:     1,
		MaxSpeed:       1200,
		MinSpeed:       300,
		HighSpeed:      1000,
		MidSpeed:       800,
		LowSpeed:       400,

		lastUpdate:       time.Now(),
		tempVariation:    0,
		currentVariation: 0,
	}
}

func (f *FfuConfig) GetProductKey() string {
	return f.Product
}

func (f *FfuConfig) GetModbusAddr() int8 {
	return f.ModbusAddr
}

// 模拟温度和电流变化
func (f *FfuConfig) updateSensorData() {
	now := time.Now()
	if now.Sub(f.lastUpdate) > time.Second {
		f.lastUpdate = now
		// 压差
		f.PressureDiff = uint16(rand.Intn(100)) // 0-99Pa

		// 模拟温度变化 (±5度范围)
		f.tempVariation += (rand.Float32() - 0.5) * 2
		if f.tempVariation > 5 {
			f.tempVariation = 5
		} else if f.tempVariation < -5 {
			f.tempVariation = -5
		}
		f.Temperature = uint16(250 + int(f.tempVariation*10)) // 基础25度 + 变化

		// 模拟电流变化 (根据速度和开关状态)
		if f.SwitchStatus == 1 && f.Speed > 0 {
			// 开启状态，电流与速度相关
			baseCurrentFloat := float32(f.Speed) * 0.002 // 速度转电流系数
			f.currentVariation += (rand.Float32() - 0.5) * 0.2
			if f.currentVariation > 0.5 {
				f.currentVariation = 0.5
			} else if f.currentVariation < -0.5 {
				f.currentVariation = -0.5
			}
			f.Current = uint16((baseCurrentFloat + f.currentVariation) * 100) // 转换为小数位2的整数
		} else {
			// 关闭状态，电流接近0
			f.Current = uint16(rand.Intn(10)) // 0-0.09A的待机电流
		}
	}
}

func (f *FfuConfig) HandleData(data []byte) (out []byte, err error) {
	out = []byte{}

	// 更新传感器数据
	f.updateSensorData()

	if data[1] == 0x03 { // 读保持寄存器
		beginAddr := int(data[2])<<8 | int(data[3]) // 起始地址
		readLen := int(data[4])<<8 | int(data[5])   // 读取长度
		g.Log().Debug(context.Background(), "ffu_config读取", g.Map{"beginAddr": beginAddr, "readLen": readLen})

		out = []byte{byte(f.ModbusAddr), 0x03, byte(readLen * 2)}
		for i := 0; i < readLen; i++ {
			addr := beginAddr + i
			switch addr {
			case 0x0a: // FFU开关状态地址 (对应config_params.c中的0x0a，但这里用连续地址)
				g.Log().Debug(context.Background(), "ffu_config开关状态", g.Map{"SwitchStatus": f.SwitchStatus})
				out = append(out, byte(f.SwitchStatus>>8), byte(f.SwitchStatus))
			case 0x04: // FFU速度状态地址 (对应config_params.c中的0x04)
				g.Log().Debug(context.Background(), "ffu_config速度状态", g.Map{"Speed": f.Speed})
				out = append(out, byte(f.Speed>>8), byte(f.Speed))
			case 0x06: // FFU温度状态地址 (对应config_params.c中的0x06)
				g.Log().Debug(context.Background(), "ffu_config温度状态", g.Map{"Temperature": f.Temperature})
				out = append(out, byte(f.Temperature>>8), byte(f.Temperature))
			case 0x05: // FFU电流状态地址 (对应config_params.c中的0x05)
				g.Log().Debug(context.Background(), "ffu_config电流状态", g.Map{"Current": f.Current})
				out = append(out, byte(f.Current>>8), byte(f.Current))
			case 0x08: // 报警状态
				g.Log().Debug(context.Background(), "ffu_config报警状态", g.Map{"AlarmStatus": f.AlarmStatus})
				out = append(out, byte(f.AlarmStatus>>8), byte(f.AlarmStatus))
			case 0x09: // 压差
				g.Log().Debug(context.Background(), "ffu_config压差", g.Map{"PressureDiff": f.PressureDiff})
				out = append(out, byte(f.PressureDiff>>8), byte(f.PressureDiff))
			default:
				out = append(out, 0, 0)
			}
		}
	} else if data[1] == 0x06 { // 写单个寄存器
		addr := int(data[2])<<8 | int(data[3])
		value := uint16(data[4])<<8 | uint16(data[5])
		g.Log().Debug(context.Background(), "ffu_config控制", g.Map{"addr": addr, "value": value})

		switch addr {
		case 0x0a: // FFU开关控制地址 (默认0x0a)
			f.SwitchStatus = value
			g.Log().Info(context.Background(), "FFU开关控制", g.Map{"status": value})
		case 0x0b: // FFU速度控制地址 (默认0x0b)
			// 限制速度范围
			if value > f.MaxSpeed {
				value = f.MaxSpeed
			} else if value < f.MinSpeed && value != 0 {
				value = f.MinSpeed
			}
			f.Speed = value
			g.Log().Info(context.Background(), "FFU速度控制", g.Map{"speed": value})
		}

		out = []byte{byte(f.ModbusAddr), 0x06, byte(addr >> 8), byte(addr), data[4], data[5]}

	} else if data[1] == 0x10 { // 写多个寄存器
		beginAddr := int(data[2])<<8 | int(data[3])
		writeLen := int(data[4])<<8 | int(data[5])
		byteCount := int(data[6])

		g.Log().Debug(context.Background(), "ffu_config批量写入", g.Map{"beginAddr": beginAddr, "writeLen": writeLen, "byteCount": byteCount})

		for i := 0; i < writeLen; i++ {
			addr := beginAddr + i
			valueIndex := 7 + i*2
			if valueIndex+1 < len(data)-2 { // 确保不越界，排除CRC
				value := uint16(data[valueIndex])<<8 | uint16(data[valueIndex+1])

				switch addr {
				case 0x0a: // 开关控制
					f.SwitchStatus = value
				case 0x0b: // 速度控制
					if value > f.MaxSpeed {
						value = f.MaxSpeed
					} else if value < f.MinSpeed && value != 0 {
						value = f.MinSpeed
					}
					f.Speed = value
				}
			}
		}

		out = []byte{byte(f.ModbusAddr), 0x10, byte(beginAddr >> 8), byte(beginAddr), byte(writeLen >> 8), byte(writeLen)}
	}

	// 添加CRC校验
	intValue := modbus.CRC16(out)
	out = append(out, byte(intValue), byte(intValue>>8))
	return
}
